package com.neusoft.hifly.commons.lang;

import java.lang.management.ManagementFactory;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang3.StringUtils;

import com.neusoft.hifly.core.log.Log;

/**
 * 日期转换类
 */
public final class DateUtil {

	/**
	 * 开始时间标配
	 */
	public final static String START_MS = " 00:00:00";

	/**
	 * 结束时间标配
	 */
	public final static String END_MS = " 23:59:59";

	public static final String DATE_PATTERN = "yyyy-MM-dd";

	public static final String TIME_PATTERN = "HH:mm:ss";

	public static final String DATE_TIME_PATTERN = DateUtil.DATE_PATTERN + " " + DateUtil.TIME_PATTERN;

	public static final String WEEKS = "MON,TUE,WED,THU,FRI,SAT,SUN";

	public static final String[] WEEKLIST = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };

	/**
	 * 默认构造方法
	 */
	private DateUtil() {
	}

	/**
	 * 获取服务器启动时间
	 */
	public static Date getServerStartDate() {
		final long time = ManagementFactory.getRuntimeMXBean().getStartTime();
		return new Date(time);
	}

	/**
	 * 日期转字符串类型
	 *
	 * @param aDate
	 *            日期对象
	 * @return 日期格式 DATA_PATTERN
	 */
	public static String dateToStr(final Date aDate) {
		SimpleDateFormat df = null;
		String returnValue = "";
		if (aDate != null) {
			df = new SimpleDateFormat(DateUtil.DATE_PATTERN);
			returnValue = df.format(aDate);
		}
		return (returnValue);
	}

	/**
	 * 日期转字符串类型
	 *
	 * @param date
	 *            日期类型
	 * @return 日期格式 DATE_TIME_PATTERN
	 */
	public static String dateTimeToStr(final Date date) {
		return DateUtil.dateToStr(date, DateUtil.DATE_TIME_PATTERN);
	}

	/**
	 * 日期转换为字符串
	 *
	 * @author Charles
	 * @param date
	 *            日期
	 * @param format
	 *            参数模板为用户自定义模板例如: yyyy-MM-dd HH:mm:ss
	 * @return 返回一个根据模板将日期类型转换的字符串。若按照format转换错误，则默认使用 DATA_PATTERN类型进行转换
	 */
	public static String dateToStr(final Date date, final String format) {
		SimpleDateFormat df = null;
		String returnValue = "";
		if (date != null) {
			df = new SimpleDateFormat(format);
			try {
				returnValue = df.format(date);
			} catch (final Exception pe) {
				Log.error(String.format("根据指定日期格式 {} 转换异常,改用默认格式 {} 进行转换.",
						new Object[] { format, DateUtil.DATE_PATTERN }));
				df = new SimpleDateFormat(DateUtil.DATE_PATTERN);
				try {
					returnValue = df.format(date);
				} catch (final Exception e) {
					Log.error(String.format("根据指定日期格式 {} 和默认格式 {} 进行转换均失败.",
							new Object[] { format, DateUtil.DATE_PATTERN }));
					Log.error(e.getMessage());
				}
			}
		}
		return (returnValue);
	}

	/**
	 * 统一的页面显示时间：yyyy-MM-dd HH:mm
	 *
	 * @param date
	 *            日期
	 * @return 格式化后的日期
	 */
	public static String showTime(final Date date) {
		return DateUtil.dateToStr(date, "yyyy-MM-dd HH:mm");
	}

	/**
	 * 邮件方式的日期格式
	 * <p>
	 * 后天的日期格式：后天 HH:mm
	 * <p>
	 * 明天的日期格式：明天 HH:mm
	 * <p>
	 * 当天的日期格式：今天 HH:mm
	 * <p>
	 * 昨天的日期格式：昨天 HH:mm
	 * <p>
	 * 前天的日期格式：前天 HH:mm
	 * <p>
	 * 一周以内的日期格式：MM/dd(星期一)
	 * <p>
	 * 更远的日期格式：yyyy/MM/dd
	 *
	 * @author Charles (Li Hui)
	 * @param date
	 *            日期
	 * @return 格式化后的日期
	 */
	public static String emailTimer(final Date date) {
		if (date != null) {
			// 校验时，以日为单位
			final long between = DateUtil.getDaysBetweenTwoDates(DateUtil.formatDate(new Date()),
					DateUtil.formatDate(date));
			String time = DateUtil.dateToStr(date, "HH:mm");
			// 判断时:分是否是00:00,若是，则去掉
			if ("00:00".equalsIgnoreCase(time)) {
				time = "";
			}
			if (between == -1) {
				// 昨天的日期格式
				return "昨天 " + time;
			} else if (between == -2) {
				// 前天的日期格式
				return "前天 " + time;
			} else if (between == 0) {
				// 当天的日期格式
				return "今天 " + time;
			} else if (between == 1) {
				// 明天的日期格式
				return "明天 " + time;
			} else if (between == 2) {
				// 后天的日期格式
				return "后天 " + time;
			} else if (between < 0 && between >= -7) {
				// 一周以内的日期格式
				return DateUtil.dateToStr(date, "MM/dd") + "(" + DateUtil.getWeekOfDateStr(date) + ")";
			} else {
				// 更远的日期格式
				return DateUtil.dateToStr(date, "yyyy/MM/dd");
			}
		}
		return "";
	}

	/**
	 * 按照日期格式，将字符串解析为日期对象
	 *
	 * @param strDate
	 *            (格式 yyyy-MM-dd)
	 * @return 日期对象,格式为DATA_PATTERN
	 */
	public static Date strToDate(final String strDate) {
		return DateUtil.strToDate(DateUtil.DATE_PATTERN, strDate);
	}

	/**
	 * 按照日期格式，将字符串解析为日期对象
	 *
	 * @param strDate
	 *            (格式 yyyy-MM-dd HH:mm:ss)
	 * @return 日期对象,格式为DATE_TIME_PATTERN
	 */
	public static Date strToDateTime(final String strDate) {
		return DateUtil.strToDate(DateUtil.DATE_TIME_PATTERN, strDate);
	}

	/**
	 * 将字符串解析为日期对象
	 *
	 * @param format
	 *            输入字符串的格式
	 * @param strDate
	 *            一个按format格式排列的日期的字符串描述
	 * @return 日期格式。若按照format转换错误，则默认使用 DATA_PATTERN类型进行转换
	 * @see java.text.SimpleDateFormat
	 */
	public static Date strToDate(String format, final String strDate) {
		Date date = null;
		if (StringUtils.isNotEmpty(strDate)) {
			if (StringUtils.isEmpty(format)) {
				format = DateUtil.DATE_PATTERN;
			}
			SimpleDateFormat df = null;
			df = new SimpleDateFormat(format);
			try {
				date = df.parse(strDate);
			} catch (final ParseException pe) {
				df = new SimpleDateFormat(DateUtil.DATE_PATTERN);
				try {
					date = df.parse(strDate);
				} catch (final ParseException e) {
					// 处理Excel导入的默认日期格式
					df = new SimpleDateFormat("dd/MM/yyyy");
					try {
						date = df.parse(strDate);
					} catch (final ParseException e1) {
						// 处理Excel导入的默认日期格式
						df = new SimpleDateFormat("yyyy/MM/dd");
						try {
							date = df.parse(strDate);
						} catch (final ParseException e2) {
							Log.error(e2.getMessage());
						}
					}
				}
			}
		}
		return (date);
	}

	/**
	 * 获取当前时间段是上午还是下午
	 *
	 * @author Charles (Li Hui)
	 * @date 2013-10-30 下午12:21:06
	 * @return 上午、下午
	 */
	public static String getAmOrPm() {
		final Calendar cal = Calendar.getInstance();
		final int type = cal.get(Calendar.AM_PM);
		if (type == 1) {
			return "下午";
		} else {
			return "上午";
		}
	}

	/**
	 * 根据默认格式获取当前时间
	 *
	 * @return 日期格式 DATA_PATTERN
	 */
	public static Calendar getToday() {
		final SimpleDateFormat df = new SimpleDateFormat(DateUtil.DATE_PATTERN);
		final String todayAsString = df.format(new Date());
		final Calendar cal = new GregorianCalendar();
		cal.setTime(DateUtil.strToDate(todayAsString));
		return cal;
	}

	/**
	 * 获取当前日期
	 *
	 * @return String
	 */
	public static String getCurrentDate() {
		final SimpleDateFormat bartDateFormat = new SimpleDateFormat(DateUtil.DATE_PATTERN);
		final Date date = new Date();
		final String str = bartDateFormat.format(date);
		return str;
	}

	/**
	 * 获取当前时间
	 *
	 * @return String
	 */
	public static String getCurrentDateTime() {
		final SimpleDateFormat bartDateFormat = new SimpleDateFormat(DateUtil.DATE_TIME_PATTERN);
		final Date date = new Date();
		final String str = bartDateFormat.format(date);
		return str;
	}

	/**
	 * 格式化日期
	 *
	 * @param date
	 *            日期
	 * @return 日期格式 DATA_PATTERN
	 */
	public static Date formatDate(final Date date) {
		final SimpleDateFormat df = new SimpleDateFormat(DateUtil.DATE_PATTERN);
		return DateUtil.strToDate(df.format(date));
	}

	/**
	 * 格式化日期
	 *
	 * @param date
	 *            日期
	 * @return 日期格式 DATA_PATTERN
	 */
	public static Date formatDate(final String format, final Date date) {
		final SimpleDateFormat df = new SimpleDateFormat(format);
		return DateUtil.strToDate(format, df.format(date));
	}

	/**
	 * @param 要转换的毫秒数
	 * @return 该毫秒数转换为 * days * hours * minutes * seconds 后的格式
	 * @author fy.zhang
	 */
	public static String formatDuring(final long mss) {
		final StringBuffer result = new StringBuffer("");
		if (mss < 1000) {
			// 不到1秒的
			result.append(mss + "毫秒");
		} else {
			// 大于1秒的

			final long days = mss / (1000 * 60 * 60 * 24);
			final long hours = (mss % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60);
			final long minutes = (mss % (1000 * 60 * 60)) / (1000 * 60);
			final long seconds = (mss % (1000 * 60)) / 1000;

			if (days >= 1) {
				result.append(days + "天");
			}
			if (hours >= 1) {
				result.append(hours + "小时");
			}
			if (minutes >= 1) {
				result.append(minutes + "分");
			}
			result.append(seconds + "秒");
		}
		return result.toString();
	}

	/**
	 * 格式化时间
	 *
	 * @param date
	 *            日期
	 * @return 日期格式 DATE_TIME_PATTERN
	 */
	public static Date formatDateTime(final Date date) {
		final SimpleDateFormat df = new SimpleDateFormat(DateUtil.DATE_TIME_PATTERN);
		return DateUtil.strToDate(df.format(date));
	}

	/**
	 * 计算两个时间差
	 */
	public static String getDatePoor(final Date endDate, final Date nowDate) {
		final long nd = 1000 * 24 * 60 * 60;
		final long nh = 1000 * 60 * 60;
		final long nm = 1000 * 60;
		// long ns = 1000;
		// 获得两个时间的毫秒时间差异
		final long diff = endDate.getTime() - nowDate.getTime();
		// 计算差多少天
		final long day = diff / nd;
		// 计算差多少小时
		final long hour = diff % nd / nh;
		// 计算差多少分钟
		final long min = diff % nd % nh / nm;
		// 计算差多少秒//输出结果
		// long sec = diff % nd % nh % nm / ns;
		return day + "天" + hour + "小时" + min + "分钟";
	}

	/**
	 * 校验两个日期大小
	 *
	 * @author Charles
	 * @param start
	 *            开始时间
	 * @param end
	 *            结束时间
	 * @return 大于：true，小于：false
	 */
	public static boolean checkTime(final Date start, final Date end) {
		if (start == null && end == null) {
			return false;
		}
		if (start == null && end != null) {
			return false;
		}
		if (start != null && end == null) {
			return true;
		}
		if ((start.getTime() - end.getTime()) > 0) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 获取日期年
	 *
	 * @param date
	 *            时间
	 * @return 年份
	 */
	public static String getCurrentYearStr(final Date date) {
		final SimpleDateFormat bartDateFormat = new SimpleDateFormat("yyyy");
		return bartDateFormat.format(date);
	}

	/**
	 * 得到两个日期之间相差多少天
	 *
	 * @param firstDate
	 *            firstDate
	 * @param secondDate
	 *            secondDate
	 * @return 相差天数
	 */
	public static int dateMinus(final Date firstDate, final Date secondDate) {
		final SimpleDateFormat sdf = new SimpleDateFormat(DateUtil.DATE_PATTERN);
		final String fir = sdf.format(firstDate);
		final String sec = sdf.format(secondDate);
		return DateUtil.dateMinus(fir, sec);
	}

	/**
	 * 得到两个日期之间相差多少天
	 *
	 * @param frontdate
	 *            相对比较小的日期 yyyy-mm-dd
	 * @param afterdate
	 *            相对比较大的日期 yyyy-mm-dd
	 * @return dateMinus
	 */
	public static int dateMinus(final String frontdate, final String afterdate) {
		final String[] front = frontdate.split("-");
		final String[] after = afterdate.split("-");
		String frontYear = null;
		String frontMon = null;
		String frontDay = null;
		String afterYear = null;
		String aftertMon = null;
		String afterDay = null;
		frontYear = front[0];
		frontMon = front[1].replaceAll("0", "");
		frontDay = front[2];
		if (Integer.parseInt(frontDay) < 10) {
			afterDay = after[2].replaceAll("0", "");
		} else {
			afterDay = after[2];
		}
		afterYear = after[0];

		aftertMon = after[1];
		if (Integer.parseInt(aftertMon) < 10) {
			aftertMon = after[1].replaceAll("0", "");
		}

		afterDay = after[2];

		// 注释：30=3 的功能
		if (Integer.parseInt(afterDay) < 10) {
			afterDay = after[2].replaceAll("0", "");
		}
		final Calendar cal = Calendar.getInstance();

		cal.set(Integer.parseInt(frontYear), Integer.parseInt(frontMon) - 1, Integer.parseInt(frontDay));
		final Date tempd1 = cal.getTime();
		cal.set(Integer.parseInt(afterYear), Integer.parseInt(aftertMon) - 1, Integer.parseInt(afterDay));
		final Date tempd2 = cal.getTime();
		final long minus = tempd2.getTime() - tempd1.getTime();
		return (int) (minus / 60 / 60 / 24 / 1000);
	}

	/**
	 * 两个日期之间相隔的天数
	 *
	 * @param dateFrom
	 *            开始时间
	 * @param dateEnd
	 *            结束时间
	 * @return 天数。返回正数，则表示dateFrom早于dateEnd，否则表示dateFrom晚于dateEnd
	 */
	public static long getDaysBetweenTwoDates(final Date dateFrom, final Date dateEnd) {
		if ((dateFrom == null) || (dateEnd == null)) {
			return 0;
		}
		final long begin = dateFrom.getTime();
		final long end = dateEnd.getTime();
		final long inter = end - begin;
		//		if (inter < 0) {
		//			inter = inter * (-1);
		//		}
		final long dateMillSec = 24 * 60 * 60 * 1000;
		long dateCnt = inter / dateMillSec;
		final long remainder = inter % dateMillSec;
		if (remainder != 0) {
			dateCnt++;
		}
		return dateCnt;
	}

	/**
	 * 一个日期型，减去或加上一个小时，求出日期结果
	 *
	 * @author 李辉
	 * @date Dec 16, 2008 1:09:40 AM
	 * @param date
	 *            日期
	 * @param num
	 *            小时数（可为负数）
	 * @return 日期结果
	 */
	public static Date hourNum(final Date date, final double num) {
		final java.util.Calendar cal = java.util.Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.MINUTE, (int) (num * 60));
		return cal.getTime();
	}

	/**
	 * 一个日期型，减去或加上一个整形，求出日期结果
	 *
	 * @author Charles
	 * @date Dec 16, 2008 1:09:40 AM
	 * @param date
	 *            日期
	 * @param type
	 *            类型：天Calendar.DATE、小时Calendar.HOUR、分钟Calendar.MINUTE 等
	 * @param num
	 *            数（可为负数）
	 * @return 日期结果
	 */
	public static String dateNum(final Date date, final int type, final int num) {
		final GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		gc.add(type, num);
		return DateUtil.dateToStr(gc.getTime(), DateUtil.DATE_TIME_PATTERN);
	}

	/**
	 * 一个日期型，减去或加上一个整形，求出日期结果
	 *
	 * @author Charles
	 * @date Dec 16, 2008 1:09:40 AM
	 * @param date
	 *            日期
	 * @param type
	 *            类型：天Calendar.DATE、小时Calendar.HOUR、分钟Calendar.MINUTE 等
	 * @param num
	 *            数（可为负数）
	 * @return 日期结果
	 */
	public static String dateNum(final Date date, final int type, final int num, final String format) {
		final GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		gc.add(type, num);
		return DateUtil.dateToStr(gc.getTime(), format);
	}

	/**
	 * 功能: 比较指定两日期如果date1晚于date2则return false; 精确到秒
	 *
	 * @param date1
	 *            日期1
	 * @param date2
	 *            日期2
	 * @return boolean
	 */
	public static boolean secondCompare(final Date date1, final Date date2) {
		boolean bea = false;
		if (date2.after(date1)) {
			bea = true;
		}
		return bea;
	}

	/**
	 * 功能: 比较指定两日期如果str1晚于str2则return false; 精确到秒
	 *
	 * @param str1
	 *            日期1
	 * @param str2
	 *            日期2
	 * @return boolean
	 */
	public static boolean secondCompare(final String str1, final String str2) {
		boolean bea = false;
		final SimpleDateFormat sdf = new SimpleDateFormat(DateUtil.DATE_TIME_PATTERN);
		java.util.Date date1;
		java.util.Date date0;
		try {
			date1 = sdf.parse(str1);
			date0 = sdf.parse(str2);
			if (date0.after(date1)) {
				bea = true;
			}
		} catch (final ParseException e) {
			bea = false;
			Log.error(e.getMessage());
		}
		return bea;
	}

	/**
	 * 功能: 比较指定两日期如果str1晚于str2则return flase; 精确到天
	 *
	 * @author Charles
	 * @dataTime 2008-5-8 上午09:06:50
	 * @param str1
	 *            日期1
	 * @param str2
	 *            日期2
	 * @return boolean
	 */
	public static boolean dateCompare(final String str1, final String str2) {
		boolean bea = false;
		final SimpleDateFormat sdf = new SimpleDateFormat(DateUtil.DATE_PATTERN);
		java.util.Date date1;
		java.util.Date date0;
		try {
			date1 = sdf.parse(str1);
			date0 = sdf.parse(str2);
			if (date0.after(date1)) {
				bea = true;
			}
		} catch (final ParseException e) {
			bea = false;
		}
		return bea;
	}

	/**
	 * 功能:计算两个日期相隔的具体时间
	 *
	 * @author Charles
	 * @dataTime 2008-5-13 下午06:02:00
	 * @param beginTime
	 *            开始时间
	 * @param endtime
	 *            结束时间
	 * @return 几天几小时几分几秒
	 */
	public static String getBetweenDayTime(final Date beginTime, final Date endtime) {
		if ((beginTime == null) || (endtime == null)) {
			return "0天";
		}
		final long l = endtime.getTime() - beginTime.getTime();
		final long day = l / (24 * 60 * 60 * 1000);
		final long hour = (l / (60 * 60 * 1000) - day * 24);
		final long min = ((l / (60 * 1000)) - day * 24 * 60 - hour * 60);
		final long s = (l / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
		final StringBuffer sb = new StringBuffer();
		if (day != 0) {
			sb.append(day + "天");
		}
		if (hour != 0) {
			sb.append(hour + "小时");
		}
		if (min != 0) {
			sb.append(min + "分");
		}
		if (s != 0) {
			sb.append(s + "秒");
		}
		System.out.println(sb);
		return sb.toString();
	}

	/**
	 * 功能:计算两个日期相隔的具体时间
	 *
	 * @author Charles
	 * @param beginTime
	 *            开始时间
	 * @param endtime
	 *            结束时间
	 * @param unit
	 *            单位
	 * @return 依据类型返回结果
	 */
	public static final long between(final String beginTime, final String endtime, final DateUnit unit) {
		return DateUtil.between(DateUtil.strToDateTime(beginTime), DateUtil.strToDateTime(endtime), unit);
	}

	/**
	 * 功能:计算两个日期相隔的具体时间
	 *
	 * @author Charles
	 * @param beginTime
	 *            开始时间
	 * @param endtime
	 *            结束时间
	 * @param unit
	 *            单位
	 * @return 依据类型返回结果
	 */
	public static final long between(final Date beginTime, final Date endtime, final DateUnit unit) {
		if (beginTime == null || endtime == null) {
			return 0;
		}
		final long diff = endtime.getTime() - beginTime.getTime();
		return diff / unit.getMillis();
	}

	/**
	 * 毫秒转小时
	 *
	 * @param millis
	 *            毫秒
	 * @return 小时
	 */
	public static long millisToHour(final long millis) {
		return TimeUnit.MILLISECONDS.toHours(millis);
	}

	/**
	 * 毫秒转分钟
	 *
	 * @param millis
	 *            毫秒
	 * @return 分钟
	 */
	public static long millisToMinutes(final long millis) {
		return TimeUnit.MILLISECONDS.toMinutes(millis);
	}

	/**
	 * 判断time是否在from，to之内
	 *
	 * @param time
	 *            指定日期
	 * @param from
	 *            开始日期
	 * @param to
	 *            结束日期
	 * @return
	 */
	public static boolean isInDate(final Date time, final Date from, final Date to) {
		if (time == null || from == null || to == null) {
			return false;
		}
		final Calendar date = Calendar.getInstance();
		date.setTime(time);

		final Calendar after = Calendar.getInstance();
		after.setTime(from);

		final Calendar before = Calendar.getInstance();
		before.setTime(to);

		if (date.after(after) && date.before(before)) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 判断指定日期的年份是否是闰年
	 *
	 * @return 否是闰年
	 */
	public static boolean isLeapYear() {
		final Calendar cal = Calendar.getInstance();
		final int year = cal.get(Calendar.YEAR);
		return DateUtil.isLeapYear(year);
	}

	/**
	 * 判断指定年份是否是闰年
	 *
	 * @author Charles
	 * @date Dec 16, 2008 1:11:10 AM
	 * @param year
	 *            指定年份
	 * @return 否是闰年
	 */
	public static boolean isLeapYear(final int year) {
		/**
		 * 详细设计： 1.被400整除是闰年，否则： 2.不能被4整除则不是闰年 3.能被4整除同时不能被100整除则是闰年 3.能被4整除同时能被100整除则不是闰年
		 */
		if ((year % 400) == 0) {
			return true;
		} else if ((year % 4) == 0) {
			if ((year % 100) == 0) {
				return false;
			} else {
				return true;
			}
		} else {
			return false;
		}
	}

	/**
	 * 判断指定日期的年份是否是闰年
	 *
	 * @param date
	 *            指定日期。
	 * @return 是否闰年
	 */
	public static boolean isLeapYear(final Date date) {
		/**
		 * 详细设计： 1.被400整除是闰年，否则： 2.不能被4整除则不是闰年 3.能被4整除同时不能被100整除则是闰年 3.能被4整除同时能被100整除则不是闰年
		 */

		final GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		final int year = gc.get(Calendar.YEAR);
		return DateUtil.isLeapYear(year);
	}

	/**
	 * 判断指定日期的年份是否是闰年
	 *
	 * @param gc
	 *            指定日期。
	 * @return 是否闰年
	 */
	public static boolean isLeapYear(final Calendar gc) {
		/**
		 * 详细设计： 1.被400整除是闰年，否则： 2.不能被4整除则不是闰年 3.能被4整除同时不能被100整除则是闰年 3.能被4整除同时能被100整除则不是闰年
		 */
		final int year = gc.get(Calendar.YEAR);
		return DateUtil.isLeapYear(year);
	}

	/**
	 * 获取当年的第一天
	 *
	 * @param year
	 * @return
	 */
	public static Date getCurrYearFirst() {
		final Calendar currCal = Calendar.getInstance();
		final int currentYear = currCal.get(Calendar.YEAR);
		return DateUtil.getYearFirst(currentYear);
	}

	/**
	 * 获取当年的最后一天
	 *
	 * @param year
	 * @return
	 */
	public static Date getCurrYearLast() {
		final Calendar currCal = Calendar.getInstance();
		final int currentYear = currCal.get(Calendar.YEAR);
		return DateUtil.getYearLast(currentYear);
	}

	/**
	 * 获取某年第一天日期
	 *
	 * @param year
	 *            年份
	 * @return Date
	 */
	public static Date getYearFirst(final int year) {
		final Calendar calendar = Calendar.getInstance();
		calendar.clear();
		calendar.set(Calendar.YEAR, year);
		final Date currYearFirst = calendar.getTime();
		return currYearFirst;
	}

	/**
	 * 获取某年最后一天日期
	 *
	 * @param year
	 *            年份
	 * @return Date
	 */
	public static Date getYearLast(final int year) {
		final Calendar calendar = Calendar.getInstance();
		calendar.clear();
		calendar.set(Calendar.YEAR, year);
		calendar.roll(Calendar.DAY_OF_YEAR, -1);
		final Date currYearLast = calendar.getTime();

		return currYearLast;
	}

	/**
	 * 取得指定日期的所处星期的第一天
	 *
	 * @param date
	 *            指定日期。
	 * @return 指定日期的所处星期的第一天
	 */
	public static Date getFirstDayOfWeek(final Date date) {
		/**
		 * 详细设计： 1.如果date是星期日，则减0天 2.如果date是星期一，则减1天 3.如果date是星期二，则减2天 4.如果date是星期三，则减3天 5.如果date是星期四，则减4天
		 * 6.如果date是星期五，则减5天 7.如果date是星期六，则减6天
		 */
		final GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		switch (gc.get(Calendar.DAY_OF_WEEK)) {
			case (Calendar.SUNDAY):
				gc.add(Calendar.DATE, 0);
				break;
			case (Calendar.MONDAY):
				gc.add(Calendar.DATE, -1);
				break;
			case (Calendar.TUESDAY):
				gc.add(Calendar.DATE, -2);
				break;
			case (Calendar.WEDNESDAY):
				gc.add(Calendar.DATE, -3);
				break;
			case (Calendar.THURSDAY):
				gc.add(Calendar.DATE, -4);
				break;
			case (Calendar.FRIDAY):
				gc.add(Calendar.DATE, -5);
				break;
			case (Calendar.SATURDAY):
				gc.add(Calendar.DATE, -6);
				break;
			default:
				break;
		}
		return gc.getTime();
	}

	/**
	 * 取得指定日期的所处星期的第一天
	 *
	 * @param gc
	 *            参数为Calendar类型
	 * @return 指定日期的所处星期的第一天
	 */
	public static Calendar getFirstDayOfWeek(final Calendar gc) {
		/**
		 * 详细设计： 1.如果date是星期日，则减0天 2.如果date是星期一，则减1天 3.如果date是星期二，则减2天 4.如果date是星期三，则减3天 5.如果date是星期四，则减4天
		 * 6.如果date是星期五，则减5天 7.如果date是星期六，则减6天
		 */
		switch (gc.get(Calendar.DAY_OF_WEEK)) {
			case (Calendar.SUNDAY):
				gc.add(Calendar.DATE, 0);
				break;
			case (Calendar.MONDAY):
				gc.add(Calendar.DATE, -1);
				break;
			case (Calendar.TUESDAY):
				gc.add(Calendar.DATE, -2);
				break;
			case (Calendar.WEDNESDAY):
				gc.add(Calendar.DATE, -3);
				break;
			case (Calendar.THURSDAY):
				gc.add(Calendar.DATE, -4);
				break;
			case (Calendar.FRIDAY):
				gc.add(Calendar.DATE, -5);
				break;
			case (Calendar.SATURDAY):
				gc.add(Calendar.DATE, -6);
				break;
			default:
				break;
		}
		return gc;
	}

	/**
	 * 取得指定日期的所处星期的最后一天
	 *
	 * @param date
	 *            指定日期。
	 * @return Date类型 指定日期的所处星期的最后一天
	 */
	public static Date getLastDayOfWeek(final Date date) {
		/**
		 * 详细设计： 1.如果date是星期日，则加6天 2.如果date是星期一，则加5天 3.如果date是星期二，则加4天 4.如果date是星期三，则加3天 5.如果date是星期四，则加2天
		 * 6.如果date是星期五，则加1天 7.如果date是星期六，则加0天
		 */
		final GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		switch (gc.get(Calendar.DAY_OF_WEEK)) {
			case (Calendar.SUNDAY):
				gc.add(Calendar.DATE, 6);
				break;
			case (Calendar.MONDAY):
				gc.add(Calendar.DATE, 5);
				break;
			case (Calendar.TUESDAY):
				gc.add(Calendar.DATE, 4);
				break;
			case (Calendar.WEDNESDAY):
				gc.add(Calendar.DATE, 3);
				break;
			case (Calendar.THURSDAY):
				gc.add(Calendar.DATE, 2);
				break;
			case (Calendar.FRIDAY):
				gc.add(Calendar.DATE, 1);
				break;
			case (Calendar.SATURDAY):
				gc.add(Calendar.DATE, 0);
				break;
			default:
				break;
		}
		return gc.getTime();
	}

	/**
	 * 取得指定日期的下一个星期的第一天
	 *
	 * @param date
	 *            指定日期。
	 * @return Date类型 指定日期的下一个星期的第一天
	 */
	public static Date getFirstDayOfNextWeek(final Date date) {
		// 1.调用getNextWeek设置当前时间 2.以1为基础，调用getFirstDayOfWeek
		final GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		gc.setTime(DateUtil.getNextWeek(gc.getTime()));
		gc.setTime(DateUtil.getFirstDayOfWeek(gc.getTime()));
		return gc.getTime();
	}

	/**
	 * 取得指定日期的下一个星期的第一天
	 *
	 * @param gc
	 *            指定日期。
	 * @return Calendar类型 指定日期的下一个星期的第一天
	 */
	public static Calendar getFirstDayOfNextWeek(final Calendar gc) {
		// 详细设计： 1.调用getNextWeek设置当前时间 2.以1为基础，调用getLastDayOfWeek
		gc.setTime(DateUtil.getNextWeek(gc.getTime()));
		gc.setTime(DateUtil.getFirstDayOfWeek(gc.getTime()));
		return gc;
	}

	/**
	 * 取得指定日期的下一个星期的最后一天
	 *
	 * @param date
	 *            指定日期。
	 * @return 指定日期的下一个星期的最后一天
	 */
	public static Date getLastDayOfNextWeek(final Date date) {
		// 详细设计： 1.调用getNextWeek设置当前时间 2.以1为基础，调用getLastDayOfWeek
		final GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		gc.setTime(DateUtil.getNextWeek(gc.getTime()));
		gc.setTime(DateUtil.getLastDayOfWeek(gc.getTime()));
		return gc.getTime();
	}

	/**
	 * 取得指定日期的下一个星期
	 *
	 * @param date
	 *            指定日期。
	 * @return 指定日期的下一个星期
	 */
	public static Date getNextWeek(final Date date) {
		// 1.指定日期加7天
		final GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		gc.add(Calendar.DATE, 7);
		return gc.getTime();
	}

	/**
	 * 取得指定日期的下一个星期
	 *
	 * @param gc
	 *            指定日期。
	 * @return 指定日期的下一个星期
	 */
	public static Calendar getNextWeek(final Calendar gc) {
		// 1.指定日期加7天
		gc.add(Calendar.DATE, 7);
		return gc;
	}

	/**
	 * 取得指定日期的上一个星期
	 *
	 * @param date
	 *            指定日期。
	 * @return 指定日期的上一个星期
	 */
	public static Date getPreviousWeek(final Date date) {
		// 1.指定日期减7天
		final GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		gc.add(Calendar.DATE, -7);
		return gc.getTime();
	}

	/**
	 * 取得指定日期的上一个星期
	 *
	 * @param gc
	 *            指定日期。
	 * @return 指定日期的上一个星期
	 */
	public static Calendar getPreviousWeek(final Calendar gc) {
		// 1.指定日期减7天
		gc.add(Calendar.DATE, -7);
		return gc;
	}

	/**
	 * 获得给定日期所在的星期几
	 *
	 * @param date
	 *            给定日期
	 * @return 整数类型
	 */
	public static int getWeekOfDate(final Date date) {
		if (date != null) {
			final Calendar cal = Calendar.getInstance();
			cal.setTime(date);
			return cal.get(Calendar.DAY_OF_WEEK) - 1;
		} else {
			return -1;
		}
	}

	/**
	 * 获得给定日期是一年中的第几周
	 *
	 * @param date
	 *            给定日期
	 * @return 整数类型
	 */
	public static int getWeekOfYear(final Date date) {
		if (date != null) {
			final Calendar cal = Calendar.getInstance();
			cal.setTime(new Date());
			return cal.get(Calendar.WEEK_OF_YEAR) - 1;
		} else {
			return -1;
		}
	}

	/**
	 * 获取当前日期是星期几
	 *
	 * @param date
	 *            给定日期
	 * @return 当前日期是星期几
	 */
	public static String getWeekOfDateStr(final Date date) {
		if (date != null) {
			final String[] weekDays = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };
			final Calendar cal = Calendar.getInstance();
			cal.setTime(date);

			int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
			if (w < 0) {
				w = 0;
			}

			return weekDays[w];
		} else {
			return "";
		}
	}

	/*******************************************************************************************************************
	 * 获得给定日期所在的星期几
	 *
	 * @param gc
	 *            给定日期
	 * @return 整数类型
	 */
	public static int getWeekForDate(final Calendar gc) {
		return gc.get(Calendar.DAY_OF_WEEK) - 1;
	}

	// end－－－－－－－－－－－－－－－－－－－与星期有关的方法－－－－－－－－－－－－－－－－－－－－－－－－//

	// －－－－－－－－－－－－－－－－－－－与月份有关的方法－－－－－－－－－－－－－－－－－－－－－－－－//

	/**
	 * 一个月的第一天
	 */
	public static Date getFirstDate(final int YY, final int MM) {

		Calendar.getInstance();

		Date date = new Date();
		final SimpleDateFormat formatter = new SimpleDateFormat(DateUtil.DATE_PATTERN);
		try {
			date = formatter.parse(YY + "-" + MM + "-" + 1);
		} catch (final Exception e) {

			e.printStackTrace();

		}
		return date;
	}

	/**
	 * 取得指定日期的所处月份的第一天
	 *
	 * @param date
	 *            指定日期。
	 * @return Date类型指定日期的所处月份的第一天
	 */
	public static Date getFirstDayOfMonth(final Date date) {
		/**
		 * 详细设计： 1.设置为1号
		 */
		final GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		gc.set(Calendar.DAY_OF_MONTH, 1);
		return gc.getTime();
	}

	/**
	 * 取得指定日期的所处月份的第一天
	 *
	 * @param gc
	 *            指定日期。
	 * @return Calendar类型 指定日期的所处月份的第一天
	 */
	public static Calendar getFirstDayOfMonth(final Calendar gc) {
		/**
		 * 详细设计： 1.设置为1号
		 */
		gc.set(Calendar.DAY_OF_MONTH, 1);
		return gc;
	}

	/**
	 * 取得指定日期的所处月份的最后一天
	 *
	 * @param date
	 *            指定日期
	 * @return 日期类型 指定日期的所处月份的最后一天
	 */
	public static Date getLastDayOfMonth(final Date date) {
		/**
		 * 详细设计： 1.如果date在1月，则为31日 2.如果date在2月，则为28日 3.如果date在3月，则为31日 4.如果date在4月，则为30日 5.如果date在5月，则为31日
		 * 6.如果date在6月，则为30日 7.如果date在7月，则为31日 8.如果date在8月，则为31日 9.如果date在9月，则为30日 10.如果date在10月，则为31日
		 * 11.如果date在11月，则为30日 12.如果date在12月，则为31日 1.如果date在闰年的2月，则为29日
		 */
		final GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		switch (gc.get(Calendar.MONTH)) {
			case 0:
				gc.set(Calendar.DAY_OF_MONTH, 31);
				break;
			case 1:
				gc.set(Calendar.DAY_OF_MONTH, 28);
				break;
			case 2:
				gc.set(Calendar.DAY_OF_MONTH, 31);
				break;
			case 3:
				gc.set(Calendar.DAY_OF_MONTH, 30);
				break;
			case 4:
				gc.set(Calendar.DAY_OF_MONTH, 31);
				break;
			case 5:
				gc.set(Calendar.DAY_OF_MONTH, 30);
				break;
			case 6:
				gc.set(Calendar.DAY_OF_MONTH, 31);
				break;
			case 7:
				gc.set(Calendar.DAY_OF_MONTH, 31);
				break;
			case 8:
				gc.set(Calendar.DAY_OF_MONTH, 30);
				break;
			case 9:
				gc.set(Calendar.DAY_OF_MONTH, 31);
				break;
			case 10:
				gc.set(Calendar.DAY_OF_MONTH, 30);
				break;
			case 11:
				gc.set(Calendar.DAY_OF_MONTH, 31);
				break;
			default:
				break;
		}
		// 检查闰年
		if ((gc.get(Calendar.MONTH) == Calendar.FEBRUARY) && (DateUtil.isLeapYear(gc.get(Calendar.YEAR)))) {
			gc.set(Calendar.DAY_OF_MONTH, 29);
		}
		return gc.getTime();
	}

	/**
	 * 取得指定日期的所处月份的最后一天
	 *
	 * @param gc
	 *            指定日期日历
	 * @return Calendar类型指定日期的所处月份的最后一天
	 */
	public static Calendar getLastDayOfMonth(final Calendar gc) {
		/**
		 * 详细设计： 1.如果date在1月，则为31日 2.如果date在2月，则为28日 3.如果date在3月，则为31日 4.如果date在4月，则为30日 5.如果date在5月，则为31日
		 * 6.如果date在6月，则为30日 7.如果date在7月，则为31日 8.如果date在8月，则为31日 9.如果date在9月，则为30日 10.如果date在10月，则为31日
		 * 11.如果date在11月，则为30日 12.如果date在12月，则为31日 1.如果date在闰年的2月，则为29日
		 */
		switch (gc.get(Calendar.MONTH)) {
			case 0:
				gc.set(Calendar.DAY_OF_MONTH, 31);
				break;
			case 1:
				gc.set(Calendar.DAY_OF_MONTH, 28);
				break;
			case 2:
				gc.set(Calendar.DAY_OF_MONTH, 31);
				break;
			case 3:
				gc.set(Calendar.DAY_OF_MONTH, 30);
				break;
			case 4:
				gc.set(Calendar.DAY_OF_MONTH, 31);
				break;
			case 5:
				gc.set(Calendar.DAY_OF_MONTH, 30);
				break;
			case 6:
				gc.set(Calendar.DAY_OF_MONTH, 31);
				break;
			case 7:
				gc.set(Calendar.DAY_OF_MONTH, 31);
				break;
			case 8:
				gc.set(Calendar.DAY_OF_MONTH, 30);
				break;
			case 9:
				gc.set(Calendar.DAY_OF_MONTH, 31);
				break;
			case 10:
				gc.set(Calendar.DAY_OF_MONTH, 30);
				break;
			case 11:
				gc.set(Calendar.DAY_OF_MONTH, 31);
				break;
			default:
				break;
		}
		// 检查闰年
		if ((gc.get(Calendar.MONTH) == Calendar.FEBRUARY) && (DateUtil.isLeapYear(gc.get(Calendar.YEAR)))) {
			gc.set(Calendar.DAY_OF_MONTH, 29);
		}
		return gc;
	}

	/**
	 * 取得指定日期的下一个月的第一天
	 *
	 * @param date
	 *            指定日期。
	 * @return 指定日期的下一个月的第一天
	 */
	public static Date getFirstDayOfNextMonth(final Date date) {
		/**
		 * 详细设计： 1.调用getNextMonth设置当前时间 2.以1为基础，调用getFirstDayOfMonth
		 */
		final GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		gc.setTime(DateUtil.getNextMonth(gc.getTime()));
		gc.setTime(DateUtil.getFirstDayOfMonth(gc.getTime()));
		return gc.getTime();
	}

	/**
	 * 取得指定日期的下一个月的第一天
	 *
	 * @param gc
	 *            指定日期。
	 * @return 指定日期的下一个月的第一天
	 */
	public static Calendar getFirstDayOfNextMonth(final Calendar gc) {
		// 1.调用getNextMonth设置当前时间 2.以1为基础，调用getLastDayOfMonth
		gc.setTime(DateUtil.getNextMonth(gc.getTime()));
		gc.setTime(DateUtil.getFirstDayOfMonth(gc.getTime()));
		return gc;
	}

	/**
	 * 取得指定日期的下一个月的最后一天
	 *
	 * @param date
	 *            指定日期。
	 * @return 指定日期的下一个月的最后一天
	 */
	public static Date getLastDayOfNextMonth(final Date date) {
		// 1.调用getNextMonth设置当前时间 2.以1为基础，调用getLastDayOfMonth
		final GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		gc.setTime(DateUtil.getNextMonth(gc.getTime()));
		gc.setTime(DateUtil.getLastDayOfMonth(gc.getTime()));
		return gc.getTime();
	}

	/**
	 * 取得指定日期的下一年
	 *
	 * @param date
	 *            指定日期。
	 * @return 指定日期的下一年
	 */
	public static Date getNextYear(final Date date) {
		// 1.指定日期的年份加1
		final GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		gc.add(Calendar.YEAR, 1);
		return gc.getTime();
	}

	/**
	 * 取得指定日期的下一年
	 *
	 * @param gc
	 *            指定日期。
	 * @return 指定日期的下一年
	 */
	public static Calendar getNextYear(final Calendar gc) {
		// 1.指定日期的年份加1
		gc.add(Calendar.YEAR, 1);
		return gc;
	}

	/**
	 * 取得指定日期的下一个月
	 *
	 * @param date
	 *            指定日期。
	 * @return 指定日期的下一个月
	 */
	public static Date getNextMonth(final Date date) {
		// 1.指定日期的月份加1
		final GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		gc.add(Calendar.MONTH, 1);
		return gc.getTime();
	}

	/**
	 * 取得指定日期的下一个月
	 *
	 * @param gc
	 *            指定日期。
	 * @return 指定日期的下一个月
	 */
	public static Calendar getNextMonth(final Calendar gc) {
		// 1.指定日期的月份加1
		gc.add(Calendar.MONTH, 1);
		return gc;
	}

	/**
	 * 取得指定日期的上一个月
	 *
	 * @param date
	 *            指定日期。
	 * @return 指定日期的上一个月
	 */
	public static Date getPreviousMonth(final Date date) {
		// 1.指定日期的月份减1
		final GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		gc.add(Calendar.MONTH, -1);
		return gc.getTime();
	}

	/**
	 * 取得指定日期的上一个月
	 *
	 * @param gc
	 *            指定日期。
	 * @return 指定日期的上一个月
	 */
	public static Calendar getPreviousMonth(final Calendar gc) {
		// 1.指定日期的月份减1
		gc.add(Calendar.MONTH, -1);
		return gc;
	}

	/**
	 * 取得月第一天
	 *
	 * @param date
	 * @return 天
	 */
	public static Date getFirstDateOfMonth(final Date date) {
		final Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.set(Calendar.DAY_OF_MONTH, c.getActualMinimum(Calendar.DAY_OF_MONTH));
		return c.getTime();
	}

	/**
	 * 取得月最后一天
	 *
	 * @param date
	 * @return 天
	 */
	public static Date getLastDateOfMonth(final Date date) {
		final Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
		return c.getTime();
	}

	/**
	 * 取得月天数
	 *
	 * @param date
	 * @return 天数
	 */
	public static int getDayOfMonth(final Date date) {
		final Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.getActualMaximum(Calendar.DAY_OF_MONTH);
	}

	/**
	 * 取得月已经过的天数
	 *
	 * @param date
	 * @return 天数
	 */
	public static int getPassDayOfMonth(final Date date) {
		final Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.get(Calendar.DAY_OF_MONTH);
	}

	/**
	 * 取得季度第一天
	 *
	 * @param date
	 * @return
	 */
	public static Date getFirstDateOfSeason(final Date date) {
		return DateUtil.getFirstDateOfMonth(DateUtil.getSeasonDate(date)[0]);
	}

	/**
	 * 取得季度最后一天
	 *
	 * @param date
	 * @return
	 */
	public static Date getLastDateOfSeason(final Date date) {
		return DateUtil.getLastDateOfMonth(DateUtil.getSeasonDate(date)[2]);
	}

	/**
	 * 取得季度天数
	 *
	 * @param date
	 * @return
	 */
	public static int getDayOfSeason(final Date date) {
		int day = 0;
		final Date[] seasonDates = DateUtil.getSeasonDate(date);
		for (final Date date2 : seasonDates) {
			day += DateUtil.getDayOfMonth(date2);
		}
		return day;
	}

	/**
	 * 取得季度剩余天数
	 *
	 * @param date
	 * @return
	 */
	public static int getRemainDayOfSeason(final Date date) {
		return DateUtil.getDayOfSeason(date) - DateUtil.getPassDayOfSeason(date);
	}

	/**
	 * 取得季度已过天数
	 *
	 * @param date
	 * @return
	 */
	public static int getPassDayOfSeason(final Date date) {
		int day = 0;

		final Date[] seasonDates = DateUtil.getSeasonDate(date);

		final Calendar c = Calendar.getInstance();
		c.setTime(date);
		final int month = c.get(Calendar.MONTH);

		if (month == Calendar.JANUARY || month == Calendar.APRIL || month == Calendar.JULY
				|| month == Calendar.OCTOBER) {// 季度第一个月
			day = DateUtil.getPassDayOfMonth(seasonDates[0]);
		} else if (month == Calendar.FEBRUARY || month == Calendar.MAY || month == Calendar.AUGUST
				|| month == Calendar.NOVEMBER) {// 季度第二个月
			day = DateUtil.getDayOfMonth(seasonDates[0]) + DateUtil.getPassDayOfMonth(seasonDates[1]);
		} else if (month == Calendar.MARCH || month == Calendar.JUNE || month == Calendar.SEPTEMBER
				|| month == Calendar.DECEMBER) {// 季度第三个月
			day = DateUtil.getDayOfMonth(seasonDates[0]) + DateUtil.getDayOfMonth(seasonDates[1])
					+ DateUtil.getPassDayOfMonth(seasonDates[2]);
		}
		return day;
	}

	/**
	 * 取得季度月
	 *
	 * @param date
	 * @return
	 */
	public static Date[] getSeasonDate(final Date date) {
		final Date[] season = new Date[3];

		final Calendar c = Calendar.getInstance();
		c.setTime(date);

		final int nSeason = DateUtil.getSeason(date);
		if (nSeason == 1) {// 第一季度
			c.set(Calendar.MONTH, Calendar.JANUARY);
			season[0] = c.getTime();
			c.set(Calendar.MONTH, Calendar.FEBRUARY);
			season[1] = c.getTime();
			c.set(Calendar.MONTH, Calendar.MARCH);
			season[2] = c.getTime();
		} else if (nSeason == 2) {// 第二季度
			c.set(Calendar.MONTH, Calendar.APRIL);
			season[0] = c.getTime();
			c.set(Calendar.MONTH, Calendar.MAY);
			season[1] = c.getTime();
			c.set(Calendar.MONTH, Calendar.JUNE);
			season[2] = c.getTime();
		} else if (nSeason == 3) {// 第三季度
			c.set(Calendar.MONTH, Calendar.JULY);
			season[0] = c.getTime();
			c.set(Calendar.MONTH, Calendar.AUGUST);
			season[1] = c.getTime();
			c.set(Calendar.MONTH, Calendar.SEPTEMBER);
			season[2] = c.getTime();
		} else if (nSeason == 4) {// 第四季度
			c.set(Calendar.MONTH, Calendar.OCTOBER);
			season[0] = c.getTime();
			c.set(Calendar.MONTH, Calendar.NOVEMBER);
			season[1] = c.getTime();
			c.set(Calendar.MONTH, Calendar.DECEMBER);
			season[2] = c.getTime();
		}
		return season;
	}

	/**
	 * 1 第一季度 2 第二季度 3 第三季度 4 第四季度
	 *
	 * @param date
	 * @return
	 */
	public static int getSeason(final Date date) {

		int season = 0;

		final Calendar c = Calendar.getInstance();
		c.setTime(date);
		final int month = c.get(Calendar.MONTH);
		switch (month) {
			case Calendar.JANUARY:
			case Calendar.FEBRUARY:
			case Calendar.MARCH:
				season = 1;
				break;
			case Calendar.APRIL:
			case Calendar.MAY:
			case Calendar.JUNE:
				season = 2;
				break;
			case Calendar.JULY:
			case Calendar.AUGUST:
			case Calendar.SEPTEMBER:
				season = 3;
				break;
			case Calendar.OCTOBER:
			case Calendar.NOVEMBER:
			case Calendar.DECEMBER:
				season = 4;
				break;
			default:
				break;
		}
		return season;
	}

	/**
	 * 取得指定日期的下一天
	 *
	 * @param date
	 *            指定日期。
	 * @return 指定日期的下一天
	 */
	public static Date getNextDay(final Date date) {
		// 1.指定日期加1天
		final GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		gc.add(Calendar.DATE, 1);
		return gc.getTime();
	}

	/**
	 * 取得指定日期的下一天
	 *
	 * @param gc
	 *            指定日期。
	 * @return 指定日期的下一天
	 */
	public static Calendar getNextDay(final Calendar gc) {
		// 1.指定日期加1天
		gc.add(Calendar.DATE, 1);
		return gc;
	}

	/**
	 * 取得指定日期的前一天
	 *
	 * @param date
	 *            指定日期。
	 * @return 指定日期的前一天
	 */
	public static Date getPreviousDay(final Date date) {
		/**
		 * 详细设计： 1.指定日期减1天
		 */
		final GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		gc.add(Calendar.DATE, -1);
		return gc.getTime();
	}

	/**
	 * 取得指定日期的前一天
	 *
	 * @param gc
	 *            指定日期。
	 * @return 指定日期的前一天
	 */
	public static Calendar getPreviousDay(final Calendar gc) {
		/**
		 * 详细设计： 1.指定日期减1天
		 */
		gc.add(Calendar.DATE, -1);
		return gc;
	}

	/**
	 * 给定日期类型获得日期所在年
	 *
	 * @param date
	 *            指定日期
	 * @return 所在年
	 */
	public static int year(final Date date) {
		final String strDate = DateUtil.dateToStr(date, DateUtil.DATE_TIME_PATTERN).trim();
		return Integer.parseInt(strDate.substring(0, 4));
	}

	/**
	 * 给定日期类型获得日期所在月份
	 *
	 * @param date
	 *            指定日期
	 * @return 所在月份
	 */
	public static int month(final Date date) {
		final String strDate = DateUtil.dateToStr(date, DateUtil.DATE_TIME_PATTERN).trim();
		return Integer.parseInt(strDate.substring(5, 7));
	}

	/**
	 * 给定日期类型获得日期所在日
	 *
	 * @param date
	 *            指定日期
	 * @return 所在日
	 */
	public static int dayOfMonth(final Date date) {
		final String strDate = DateUtil.dateToStr(date, DateUtil.DATE_TIME_PATTERN).trim();
		return Integer.parseInt(strDate.substring(8, 10));
	}

	/**
	 * 给定日期类型获得日期所在时
	 *
	 * @param date
	 *            指定日期
	 * @return 所在时
	 */
	public static int hour(final Date date) {
		final String strDate = DateUtil.dateToStr(date, DateUtil.DATE_TIME_PATTERN).trim();
		return Integer.parseInt(strDate.substring(11, 13));
	}

	/**
	 * 给定日期类型获得日期所在秒
	 *
	 * @param date
	 *            指定日期
	 * @return 所在秒
	 */
	public static int minute(final Date date) {
		final String strDate = DateUtil.dateToStr(date, DateUtil.DATE_TIME_PATTERN).trim();
		return Integer.parseInt(strDate.substring(14, 16));
	}

	/**
	 * 给定一个日期，返回加减n天后的日期，返回Date nDaysAfterOneDate
	 *
	 * @param basicDate
	 *            Date
	 * @param n
	 *            int
	 * @return Date
	 */
	public static Date nDaysAfterOneDate(final Date basicDate, final int n) {
		return DateUtil.strToDateTime(DateUtil.dateNum(basicDate, Calendar.DATE, n));
	}

	/**
	 * 将String按照标准格式化成Date
	 *
	 * @param value
	 *            String日期
	 * @return Date日期
	 */
	public static Date convert(final Object value) {
		final SimpleDateFormat df = new SimpleDateFormat(DateUtil.DATE_PATTERN);
		if (value == null) {
			return null;
		}
		if (((String) value).trim().length() == 0) {
			return null;
		}

		if (value instanceof String) {
			try {
				return df.parse((String) value);
			} catch (final Exception ex) {
				return null;
			}
		} else {
			return null;
		}
	}

	/**
	 * 将毫秒转换为日期
	 *
	 * @author Charles
	 * @param dateFormate
	 *            日期格式
	 * @param millis
	 *            毫秒，为0是，使用当前时间
	 * @return 日期
	 */
	public static String millisToDate(String dateFormate, long millis) {
		if (StringUtils.isEmpty(dateFormate)) {
			dateFormate = DateUtil.DATE_TIME_PATTERN;
		}
		if (millis == 0) {
			millis = System.currentTimeMillis();
		}
		final Calendar cal = Calendar.getInstance();
		cal.setTimeInMillis(millis);
		final java.util.Date date = cal.getTime();
		return DateUtil.dateToStr(date, dateFormate);
	}

	/**
	 * 根据日期获取年龄
	 *
	 * @author Charles (Li Hui)
	 * @date 2011-5-9 下午03:44:35
	 * @param birthDay
	 *            出生日期
	 * @return 年龄
	 */
	public static int getAge(final Date birthDay) {
		final Calendar cal = Calendar.getInstance();

		if (cal.before(birthDay)) {
			throw new IllegalArgumentException("The birthDay is before Now.It's unbelievable!");
		}

		final int yearNow = cal.get(Calendar.YEAR);
		final int monthNow = cal.get(Calendar.MONTH);
		final int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH);
		cal.setTime(birthDay);

		final int yearBirth = cal.get(Calendar.YEAR);
		final int monthBirth = cal.get(Calendar.MONTH);
		final int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);

		int age = yearNow - yearBirth;

		if (monthNow <= monthBirth) {
			if (monthNow == monthBirth) {
				//monthNow==monthBirth
				if (dayOfMonthNow < dayOfMonthBirth) {
					age--;
				} else {
					//do nothing
				}
			} else {
				//monthNow>monthBirth
				age--;
			}
		} else {
			//monthNow<monthBirth
			//donothing
		}
		return age;
	}

	/**
	 * 当前日期
	 */
	public static String getDay() {
		final Calendar cal = Calendar.getInstance();
		final int day = cal.get(Calendar.DATE);
		return String.valueOf(day);
	}

	/**
	 * 按中国习惯，星期一到星期日编号依次为1,2,3,4,5,6,7
	 *
	 * @param dayOfWeek
	 *            传入的为Calendar字段数值。
	 * @return 序号
	 */
	public static int getChineseDayOfWeek(final int dayOfWeek) {
		switch (dayOfWeek) {
			case Calendar.MONDAY:
				return 1;
			case Calendar.TUESDAY:
				return 2;
			case Calendar.WEDNESDAY:
				return 3;
			case Calendar.THURSDAY:
				return 4;
			case Calendar.FRIDAY:
				return 5;
			case Calendar.SATURDAY:
				return 6;
			case Calendar.SUNDAY:
				return 7;
		}
		return -1;
	}

	/**
	 * 按中国习惯，星期一到星期日编号依次为1,2,3,4,5,6,7
	 *
	 * @param dayOfWeek
	 *            传入的为Calendar字段数值。
	 * @return 序号
	 */
	public static String getWeekName(final int theWeek) {
		switch (theWeek) {
			case 1:
				return "星期一";
			case 2:
				return "星期二";
			case 3:
				return "星期三";
			case 4:
				return "星期四";
			case 5:
				return "星期五";
			case 6:
				return "星期六";
			case 7:
				return "星期日";
		}
		return "日期错误";
	}

	/**
	 * 本周日期列表
	 *
	 * @param date
	 *            指定日期，默认为当天
	 * @param firstDay
	 *            周日为第一天：Calendar.SUNDAY，周一为第一天：Calendar.MONDAY
	 * @return 所有日期
	 */
	public static List<String> getWeekList(final Date date, final int firstDay) {
		final Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		// 判断要计算的日期是否是周日，如果是则减一天计算周六的，否则会出问题，计算到下一周去了
		final int dayWeek = cal.get(Calendar.DAY_OF_WEEK);// 获得当前日期是一个星期的第几天
		if (1 == dayWeek) {
			cal.add(Calendar.DAY_OF_MONTH, -1);
		}
		// 设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一
		cal.setFirstDayOfWeek(firstDay);
		// 获得当前日期是一个星期的第几天
		final int day = cal.get(Calendar.DAY_OF_WEEK);
		// 根据日历的规则，给当前日期减去星期几与一个星期第一天的差值
		cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day);

		final List<String> weekList = new ArrayList<String>(0);
		weekList.add(DateUtil.dateToStr(cal.getTime()));
		cal.add(Calendar.DATE, 1);
		weekList.add(DateUtil.dateToStr(cal.getTime()));
		cal.add(Calendar.DATE, 1);
		weekList.add(DateUtil.dateToStr(cal.getTime()));
		cal.add(Calendar.DATE, 1);
		weekList.add(DateUtil.dateToStr(cal.getTime()));
		cal.add(Calendar.DATE, 1);
		weekList.add(DateUtil.dateToStr(cal.getTime()));
		cal.add(Calendar.DATE, 1);
		weekList.add(DateUtil.dateToStr(cal.getTime()));
		cal.add(Calendar.DATE, 1);
		weekList.add(DateUtil.dateToStr(cal.getTime()));
		return weekList;
	}

	/**
	 * 本月日期列表
	 * <p>
	 * 7*5 = 35个格子，不够用空串补齐
	 *
	 * @param date
	 *            指定日期，默认为当天
	 * @return 所有日期
	 */
	@SuppressWarnings("deprecation")
	public static List<String> getMonthList(Date date) {
		final List<String> monthList = new ArrayList<String>(0);
		final Calendar cal = Calendar.getInstance();
		if (date == null) {
			date = new Date();
		}
		date.setDate(1);
		cal.setTime(date);

		/* 判断当前月第一天是星期几，若不是星期日，则用空格补齐 */
		for (int i = 1; i < cal.get(Calendar.DAY_OF_WEEK); i++) {
			monthList.add("");
		}

		/* 获取一个月的日：1-31 */
		for (int i = 1; i <= cal.getActualMaximum(Calendar.DATE); i++) {
			date.setDate(i);
			monthList.add(String.valueOf(i));

		}

		/* 补全空格 */
		cal.setTime(date);
		final int wday = cal.get(Calendar.DAY_OF_WEEK);
		for (int i = wday; i < 7; i++) {
			monthList.add("");
		}
		return monthList;
	}

	/**
	 * 获取两个日期之间的所有日期
	 * <p>
	 * 包括开始日期和结束日期两天
	 *
	 * @param startDay
	 *            开始日期
	 * @param endDay
	 *            结束日期
	 * @param format
	 *            日期格式化
	 * @return 所有日期
	 */
	public static List<String> getDayList(final Date startDay, final Date endDay, final String format) {
		// 给出的日期开始日比终了日大则不执行
		if (startDay == null || endDay == null || startDay.compareTo(endDay) > 0) {
			return null;
		}
		final List<String> list = new ArrayList<String>(0);

		// 若两个日期相等，则随便返回一个不为空的日期
		if (startDay.compareTo(endDay) == 0) {
			list.add(DateUtil.dateToStr(startDay != null ? startDay : endDay, format));
			return list;
		}

		final Calendar start = Calendar.getInstance();
		start.setTime(startDay);
		final Calendar end = Calendar.getInstance();
		end.setTime(endDay);

		// 追加开始日期
		list.add(DateUtil.dateToStr(start.getTime(), format));
		// 中间日期段
		while (true) {
			// 日期加一
			start.add(Calendar.DATE, 1);
			// 日期加一后判断是否达到终了日，达到则终止打印
			if (start.compareTo(end) >= 0) {
				break;
			}
			if (StringUtils.isNotEmpty(format)) {
				list.add(DateUtil.dateToStr(start.getTime(), format));
			} else {
				list.add(DateUtil.dateTimeToStr(start.getTime()));
			}
		}
		// 追加结束日期
		list.add(DateUtil.dateToStr(end.getTime(), format));
		StringUtil.removeListDuplicate(list);
		return list;
	}

	/**
	 * 演示
	 *
	 * @author Charles (Li Hui)
	 * @date Mar 29, 2011 4:40:40 PM
	 * @param args
	 *            参数
	 */
	public static void main(final String[] args) {
		System.out.println(
				DateUtil.dateToStr(DateUtil.strToDateTime("2020-10-16 11:26:04"), DateUtil.DATE_TIME_PATTERN).trim());
		System.out.println(DateUtil.dateToStr(DateUtil.strToDate("2020-10-16"), DateUtil.DATE_TIME_PATTERN).trim());
		// ### 计算两个日期差：毫秒
		//		System.out.println(DateUtil.getBetweenDayTimeByReturnType(DateUtil.strToDateTime("2020-10-16 11:26:04"),
		//				DateUtil.strToDateTime("2020-10-16 11:26:04"), DateUtil.MS));
		//
		//		System.out.println(DateUtil.getBetweenDayTimeByReturnType(DateUtil.strToDateTime("2020-10-16 11:26:04"),
		//				DateUtil.strToDateTime("2020-10-16 11:27:04"), DateUtil.MS));

		// ### 获取两个日期之间的所有日期
		//		final String dd = LocalDateUtil.dateToStr(LocalDateUtil.getPreviousDay(LocalDate.now()),
		//				LocalDateUtil.DEFAULT_PATTERN_DATE);
		//		final Date onOffTime = DateUtil.strToDateTime(dd + " " + DateUtil.END_MS);
		//		final List<String> dayList = DateUtil.getDayList(onOffTime, new Date(), DateUtil.DATE_PATTERN);
		//		dayList.forEach(System.out::println);

		//		List<String> dayList = getDayList(DateUtil.strToDateTime("2019-12-28 11:26:04"),
		//				DateUtil.strToDateTime("2020-01-02 11:26:04"), DATE_PATTERN);
		//		dayList.forEach(day -> {
		//			final Date now = DateUtil.strToDate(day);
		//			final String y = DateUtil.getYearForDateTime(now);
		//			final String m = DateUtil.getMonthForDateTime(now);
		//			final String d = DateUtil.getDateForDateTime(now);
		//			System.out.println(day + " -> " + y + " " + m + " " + d);
		//		});

		// ### 根据日期获取年龄
		//		System.out.println(DateUtil.getAge(DateUtil.strToDateTime("1961-04-12")));
		//		// 邮件方式的日期格式
		//		//		08/10(星期三)
		//		System.out.println(DateUtil.emailTimer(DateUtil.strToDateTime("2011-08-10 16:26:12")));
		//		//		08/09(星期二)
		//		System.out.println(DateUtil.emailTimer(DateUtil.strToDateTime("2011-08-09 16:26:12")));
		//		//		后天 16:26
		//		System.out.println(DateUtil.emailTimer(DateUtil.strToDateTime("2011-08-08 16:26:12")));
		//		//		明天 16:26
		//		System.out.println(DateUtil.emailTimer(DateUtil.strToDateTime("2011-08-07 16:26:12")));
		//		//		今天 16:26
		//		System.out.println(DateUtil.emailTimer(DateUtil.strToDateTime("2011-08-06 16:26:12")));
		//		//		昨天 16:26
		//		System.out.println(DateUtil.emailTimer(DateUtil.strToDateTime("2011-08-05 16:26:12")));
		//		//		前天 16:26
		//		System.out.println(DateUtil.emailTimer(DateUtil.strToDateTime("2011-08-04 16:26:12")));
		//		//		08/03(星期三)
		//		System.out.println(DateUtil.emailTimer(DateUtil.strToDateTime("2011-08-03 16:26:12")));
		//		//		08/02(星期二)
		//		System.out.println(DateUtil.emailTimer(DateUtil.strToDateTime("2013-12-22 16:26:12")));
		//		System.out.println(DateUtil.emailTimer(DateUtil.strToDateTime("2014-08-02 16:26:12")));
	}
}
